#!/bin/bash

# See documentation for using the reproducer script:
# README-reproducer-zuul-based-quickstart.html
# (in the same top-level logs directory as this reproducer script).

: ${WORKSPACE:=$(mktemp -d -t reproduce-tmp.XXXXX)}
: ${LIBVIRT:=0}
: ${CLOUD_NAME:="rdo-cloud"}
: ${CLOUDS_YAML_PATH:="/home/$USER/.config/openstack/clouds.yaml"}
: ${OVB_KEY_NAME:="tripleo-ci-team"}
: ${FORCE_POST_FAILURE:=0}
: ${UPSTREAM_GERRIT_USER:="$USER"}
: ${RDO_GERRIT_USER:="$USER"}
: ${USER_SSH_KEY:="id_rsa"}
: ${USER_SSH_PUB_KEY:="$USER_SSH_KEY.pub"}
: ${SSH_KEY_PATH:="/home/$USER/.ssh"}
: ${UPSTREAM_GERRIT_SSH_KEY:="id_rsa"}
: ${RDO_GERRIT_SSH_KEY:="id_rsa"}
: ${EXTRA_PARAMS:=""}
: ${CONTAINER_MODE:="podman"}
: ${OVERWRITE_WORKSPACE:="0"}

usage () {
    echo "Usage: $0 [options]"
    echo ""
    echo "Options:"
    echo "  -w, --workspace <dir>"
    echo "                      directory where the repos and directories"
    echo "                      are created. Defaults to creating a directory in /tmp"
    echo "  -l, --libvirt"
    echo "                      Runs a 2-node multinode job or singlenode job on a"
    echo "                      single virthost using libvirt to create the nodes."
    echo "                      If a singlenode reproducer is run, two VMs will still be created."
    echo "  -c, --cloud-name"
    echo "                      Host cloud, specified in the clouds.yaml, to target"
    echo "                      Defaults to rdo-cloud"
    echo "  -cp, --clouds-yaml-path"
    echo "                      Full path to the clouds.yaml file"
    echo "                      Defaults to /home/$USER/.config/openstack/clouds.yaml"
    echo "  -ok, --ovb-key-name"
    echo "                      Name of the key to use in the host tenant for OVB deployments"
    echo "                      Defaults to tripleo-ci-team"
    echo "  -f, --force-post-failure"
    echo "                      Force job to fail so that the nodes will be held."
    echo "                      Temporary solution"
    echo "  -ug, --upstream-gerrit-user"
    echo "                      Set the upstream gerrit user required to clone repos."
    echo "                      Defaults to the current $USER"
    echo "  -rg, --rdo-gerrit-user"
    echo "                      Set the upstream RDO user required to clone RDO-related repos."
    echo "                      Defaults to the current $USER"
    echo "  -k, --ssh-key"
    echo "                      private ssh key used to set up an access nodes."
    echo "                      Defaults to id_rsa."
    echo "  -kp, --ssh-key-public"
    echo "                      public ssh key used to set up an access nodes."
    echo "                      Defaults to $USER_SSH_KEY.pub"
    echo "  -skp, --ssh-key-path"
    echo "                      Path to directory where user ssh keys are stored."
    echo "                      Defaults to /home/$USER/.ssh"
    echo "  -ugk, --upstream-gerrit-key"
    echo "                      Set the upstream gerrit private key."
    echo "                      Defaults to the $USER_SSH_KEY."
    echo "  -rgk, --rdo-gerrit-key"
    echo "                      Set the upstream RDO user key."
    echo "                      Defaults to the $USER_SSH_KEY."
    echo "  -e, --extra-params"
    echo "                      File or/and parameters used to override default"
    echo "                      parameters for playbooks. Multiple files"
    echo "                      can be passed [-e @file1.yml -e @file2.yml ...]"
    echo "                      and arguments [-e var=value -e var2=value2 ...]"
    echo "  -o, --overwrite-workspace"
    echo "                      default is to not overwrite any local modifications"
    echo "                      to the workspace dir made by the user"
    echo "  -h, --help          print this help and exit"
}

set -e

# Input argument assignments
while [ "x$1" != "x" ]; do

    case "$1" in
        --workspace|-w)
            # realpath fails if /some/path doesn't exist. It is created later
            WORKSPACE=$(realpath $2 || echo -n $2)
            shift
            ;;

        --libvirt|-l)
            LIBVIRT=1
            ;;

        --cloud-name|-c)
            CLOUD_NAME=$2
            shift
            ;;

        --clouds-yaml-path|-cp)
            CLOUDS_YAML_PATH=$2
            shift
            ;;

        --ovb-key-name|-ok)
            OVB_KEY_NAME=$2
            shift
            ;;

        --force-post-failure|-f)
            FORCE_FAILURE=1
            ;;

        --upstream-gerrit-user|-ug)
            UPSTREAM_GERRIT_USER=$2
            shift
            ;;

        --rdo-gerrit-user|-rg)
            RDO_GERRIT_USER=$2
            shift
            ;;

        --ssh-key|-k)
            USER_SSH_KEY=$2
            shift
            ;;

        --ssh-key-public|-kp)
            USER_SSH_PUB_KEY=$2
            shift
            ;;

        --ssh-key-path|-skp)
            SSH_KEY_PATH=$2
            shift
            ;;

        --upstream-gerrit-key|-ugk)
            UPSTREAM_GERRIT_SSH_KEY=$2
            shift
            ;;

        --rdo-gerrit-key|-rgk)
            RDO_GERRIT_SSH_KEY=$2
            shift
            ;;

        --extra-params|-e)
            [[ ${2::1} == "@" ]] && EXTRA_PARAMS+=("-e @$(realpath ${2#@}) ") || EXTRA_PARAMS+=("-e ${2} ")
            shift
            ;;

        --container-cli|-cont)
            CONTAINER_MODE=$2
            shift
            ;;

        --overwrite-workspace|-o)
           OVERWRITE_WORKSPACE="1"
           ;;

        --help|-h)
            usage
            exit
            ;;

        --) shift
            break
            ;;

        -*) echo "ERROR: unknown option: $1" >&2
            usage >&2
            exit 2
            ;;

        *)    break
            ;;
    esac

    shift
done

set -x

if [[ "$LIBVIRT" == "1" ]]; then
    echo "check if virt flags are enabled on the cpu"
    grep -q 'vmx\|smx' /proc/cpuinfo || LIBVIRT_ERROR=true
    # grep hypervisor returns true on virt
    echo "check if linux is running in a hypervisor"
    grep -q 'hypervisor' /proc/cpuinfo && LIBVIRT_ERROR=true || true
    dmesg | grep kvm | grep -i disabled && LIBVIRT_ERROR=true || true
    if [[ ! -z "$LIBVIRT_ERROR" ]]; then
        echo -e "\e[31m ERROR: -l,  libvirt attempted on a machine w/o libvirt capabilities, or on a virtual instance \e[0m"
    fi
    if [ ! -f "$WORKSPACE/libvirt_nodepool_vars.yml" ]; then
        cp "$WORKSPACE/roles/libvirt/setup/overcloud/vars/libvirt_nodepool_vars.yml" "$WORKSPACE"
    fi

fi

curl -o bindep.txt https://raw.githubusercontent.com/rdo-infra/ansible-role-tripleo-ci-reproducer/master/bindep.txt

source install-deps.sh
# install just enough python
install_deps
# install bindep
install_bindep
# checks the $PWD for a file named
# bindep.txt and installs
# dependencies listed in the file.
install_package_deps_via_bindep
# Ensure pip is updated
sudo pip install --upgrade pip

if [[ "$CONTAINER_MODE" == "docker" ]]; then
    if [ -x "/usr/bin/docker" ] ; then
        # Fail as early as possible if the docker
        # group is not setup appropriately.
        # This has to be done AFTER package intalls.
        # Set up docker groups
        if ! groups | grep -Eq "docker|dockerroot"; then
            echo "$USER is not in the docker|dockerroot group."
            if grep -q docker: /etc/group; then
                DG=docker
            elif grep -q dockerroot: /etc/group; then
                DG=dockerroot
            elif ! grep -q docker /etc/group; then
                sudo groupadd docker
                DG=docker
            fi
            sudo usermod -aG $DG $USER
            echo -e "\e[31m WARNING: The script has exited the current shell in order to setup \
        the user groups via usermod correctly. Please re-execute the script. \e[0m"
            exec sg $DG newgrp `id -gn`
        fi

        # This can only be checked after rpms are installed.
        # Check the Docker config
        if [[ -f /etc/docker/daemon.json ]]; then
            if cat /etc/docker/daemon.json | grep '"group": "docker"'; then
                echo "docker group is already added to /etc/docker/daemon.json"
            elif cat /etc/docker/daemon.json | grep '"group": "dockerroot"'; then
                echo "dockerroot group is already added to /etc/docker/daemon.json"
            elif (( $(cat /etc/docker/daemon.json | wc -m) > 3 )); then
                echo -e "\e[31m /etc/docker/daemon.json is populated. \
                    Exit this script and either clear the file or add the docker group. \e[0m" | xargs
                exit 1
            else
                echo "The docker|dockerroot group will be added to /etc/docker/daemon.json."
            fi
        fi

        # Ensure the docker process has been restarted
        sudo systemctl restart docker
    fi
fi

# Start from a clean workspace
export WORKSPACE
if [ "$OVERWRITE_WORKSPACE" == 1 ] || [ ! -d "$WORKSPACE" ]; then
    mkdir -p $WORKSPACE
    rsync -a *-playbook.yaml $WORKSPACE
    cd $WORKSPACE

    # Run the playbook to set up the launcher env
    PATH=${HOME}/.local/bin:$PATH ansible-playbook \
        $WORKSPACE/launcher-env-setup-playbook.yaml \
        -vv \
        ${EXTRA_PARAMS[@]}
else
    cd $WORKSPACE
fi

# Set the options selected into EXTRA_PARAMS
if [[ "$LIBVIRT" == "1" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e nodepool_provider=libvirt "
    EXTRA_PARAMS="$EXTRA_PARAMS -e mirror_path=mirror.mtl01.inap.opendev.org "
fi

if [[ "$LIBVIRT" == "0" && "$CLOUD_NAME" != "rdo-cloud" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e cloud_name=$CLOUD_NAME "
fi

if [[ "$CLOUDS_YAML_PATH" != "/home/$USER/.config/openstack/clouds.yaml" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e clouds_yaml_path=$CLOUDS_YAML_PATH "
fi

if [[ "$OVB_KEY_NAME" != "tripleo-ci-team" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e ovb_key_name=$OVB_KEY_NAME "
fi

if [[ "$FORCE_POST_FAILURE" == "1" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e force_post_failure=true "
fi

if [[ "$UPSTREAM_GERRIT_USER" != "$USER" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e upstream_gerrit_user=$UPSTREAM_GERRIT_USER "
fi

if [[ "$RDO_GERRIT_USER" != "$USER" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e rdo_gerrit_user=$RDO_GERRIT_USER "
fi

if [[ "$USER_SSH_KEY" != "id_rsa" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e user_pri_key=$USER_SSH_KEY "
fi

if [[ "$USER_SSH_PUB_KEY" != "$USER_SSH_KEY.pub" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e user_pub_key=$USER_SSH_PUB_KEY "
fi

if [[ "$SSH_KEY_PATH" != "/home/$USER/.ssh" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e ssh_path=$SSH_KEY_PATH "
fi

if [[ "$UPSTREAM_GERRIT_SSH_KEY" != "$USER_SSH_KEY" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e upstream_gerrit_key=$UPSTREAM_GERRIT_SSH_KEY "
fi

if [[ "$RDO_GERRIT_SSH_KEY" != "$USER_SSH_KEY" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e rdo_gerrit_key=$RDO_GERRIT_SSH_KEY "
fi

# to customize your libvirt nodepool settings
# edit $WORKSPACE/libvirt_nodepool_vars.yml
if [[ "$LIBVIRT" == "1" ]]; then
    EXTRA_PARAMS="$EXTRA_PARAMS -e @libvirt_nodepool_vars.yml "
fi

echo "EXTRA_PARAMS = $EXTRA_PARAMS"
sleep 3

# Run the launcher playbook
PATH=${HOME}/.local/bin:$PATH ansible-playbook \
    $WORKSPACE/launcher-playbook.yaml \
    -e container_mode="$CONTAINER_MODE" \
    -vv \
    --tags all \
    ${EXTRA_PARAMS[@]}
